#ifndef CSTRENGTHMAP_H
#define CSTRENGTHMAP_H

#include <string>
#include <fstream>
#include <map>
#include "cardtypes.h"

using namespace std;

class CStrengthMap
{
public:
    CStrengthMap(const string& FileName, HANDSTENGTH baseStrength = 0)
    {
        mBaseStrength = baseStrength;
        ifstream fin(FileName);

        if ( !fin.is_open() )
            throw string("[CStrengthMap] Cannot open file: ") + FileName;

        HANDSTENGTH handStr = 0;
        HANDSIGNATURE handSignature;
        while ( !fin.eof() )
        {
            handSignature = "";
            fin >> handSignature;
            if ( handSignature.size() == 5)
            {
                handStr++;
                mValues[handSignature] = handStr;
            }
        }
        fin.close();
    };

    HANDSTENGTH getStrength(const HANDSIGNATURE& signature) const
    {
        return mBaseStrength + mValues.at(signature);
    }

private:
    map<HANDSIGNATURE, HANDSTENGTH> mValues;
    HANDSTENGTH mBaseStrength;
};

class CCardStrengthCalculator
{
public:
    CCardStrengthCalculator()
    {
        mStengthVals[ccHighCard]      = new CStrengthMap("HighCardRank.txt");
        mStengthVals[ccPair]          = new CStrengthMap("PairRank.txt", 1277);
        mStengthVals[ccTwoPairs]      = new CStrengthMap("TwoPairRank.txt", 4137);
        mStengthVals[ccThreeOfAKind]  = new CStrengthMap("ThreeOfAKindRank.txt", 4995);
        mStengthVals[ccStraight]      = new CStrengthMap("StraightRank.txt", 5853);
        mStengthVals[ccFlush]         = new CStrengthMap("FlushRank.txt", 5863);
        mStengthVals[ccFullHouse]     = new CStrengthMap("FullHouseRank.txt", 7140);
        mStengthVals[ccFourOfAKind]   = new CStrengthMap("FourOfAKindRank.txt", 7296);
        mStengthVals[ccStraightFlush] = new CStrengthMap("StraightFlushRank.txt", 7452);
        mStengthVals[ccRoyalFlush]    = new CStrengthMap("RoyalFlushRank.txt", 7461);
    }

    ~CCardStrengthCalculator()
    {
        for (auto it: mStengthVals)
            delete it.second;
    }

    HANDSTENGTH getStrength( COMBINATION_TYPE combination, HANDSIGNATURE signature ) const
    {
        return mStengthVals.at(combination)->getStrength(signature);
    }

private:
    map<COMBINATION_TYPE, CStrengthMap*> mStengthVals;
};

#endif // CSTRENGTHMAP_H

